/*
 * ashmem.h
 *
 *  Created on: 2018-3-9
 *      Author: fanghr
 */

#ifndef ASHMEM_H
#define ASHMEM_H

#define DRIVER_NAME "ashmem"
#define DEBUG

#ifdef DEBUG
#define PDEBUG(fmt,args...) printk(KERN_DEBUG"%s:"fmt,DRIVER_NAME, ##args)
#define PTRACE_FUNC PDEBUG("In function %s\n",__func__)
#define PTRACE_PROCESS PDEBUG("Process pid:%d,tgid:%d,command:%s",current->pid,current->tgid,current->comm)
#define PTRACE PTRACE_FUNC; \
	PTRACE_PROCESS
#else
#define PDEBUG(fmt,args...) do{}while(0)
#define PTRACE_FUNC do{}while(0)
#define PTRACE_PROCESS do{}while(0)
#define PTRACE PTRACE_FUNC; \
	PTRACE_PROCESS
#endif
#define PERR(fmt,args...) printk(KERN_ERR"%s:"fmt,DRIVER_NAME,##args)
#define PINFO(fmt,args...) printk(KERN_INFO"%s:"fmt,DRIVER_NAME, ##args)

#ifdef CONFIG_COMPAT
#define COMPAT_ASHMEM_SET_SIZE _IOW(__ASHMEMIOC,3,compat_size_t)
#define COMPAT_ASHMEM_SET_PROT_MASK	_IOW(__ASHMEMIOC, 5, unsigned int)
#endif

#define ASHMEM_NAME_PREFIX "dev/ashmem/"
#define ASHMEM_NAME_PREFIX_LEN (sizeof(ASHMEM_NAME_PREFIX) - 1)
#define ASHMEM_FULL_NAME_LEN (ASHMEM_NAME_LEN + ASHMEM_NAME_PREFIX_LEN)

#define range_size(range) \
	((range)->pgend - (range)->pgstart + 1)

#define range_on_lru(range) \
	((range)->purged == ASHMEM_NOT_PURGED)

#define page_range_subsumes_range(range, start, end) \
	(((range)->pgstart >= (start)) && ((range)->pgend <= (end)))

#define page_range_subsumed_by_range(range, start, end) \
	(((range)->pgstart <= (start)) && ((range)->pgend >= (end)))

#define page_in_range(range, page) \
	(((range)->pgstart <= (page)) && ((range)->pgend >= (page)))

#define page_range_in_range(range, start, end) \
	(page_in_range(range, start) || page_in_range(range, end) || \
		page_range_subsumes_range(range, start, end))

#define range_before_page(range, page) \
	((range)->pgend < (page))

#define PROT_MASK		(PROT_EXEC | PROT_READ | PROT_WRITE)
#endif

#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kdev_t.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/uaccess.h>
#include <linux/limits.h>
#include <linux/ioctl.h>
#include <linux/compat.h>
#include <linux/mm.h>
#include <linux/file.h>
#include <linux/falloc.h>
#include <linux/mman.h>
#include <linux/mutex.h>
#include <linux/shmem_fs.h>
#include <linux/personality.h>
#include <linux/miscdevice.h>
#include <linux/bitops.h>
#include <linux/list.h>
#include "uapi_ashmem.h"

//lru:缓存淘汰算法

/**
 * struct ashmem_area:匿名共享内存区
 * @name:显示在/proc/pid/maps中的可选的名字
 * @unpinned_list:unpinned页的列表
 * @file:shmem的基础文件
 * @prot_mask:允许的保护位，如vm_flags
 * 生命周期:从open()到release(),由ashmem_mutex保护
 */
struct ashmem_area {
	char name[ASHMEM_FULL_NAME_LEN];
	struct list_head unpinned_list;
	struct file *file;
	size_t size;
	unsigned long prot_mask;
};

/**
 * struct ashmem_range:一系列unpinned的页
 * @lru:lru列表入口
 * @unpinned:该区域中unpinned的列表入口
 * @asma:关联的ashmem区域
 * @pgstart:第一个内存页
 * @pgend:最后一个内存页
 * @purged:清除状态（ASHMEM_NOT或ASHMEM_WAS_PURGED）
 * 生命周期:从unpin到pin,由ashmem_mutex保护
 */
struct ashmem_range {
	struct list_head lru;
	struct list_head unpinned;
	struct ashmem_area *asma;
	size_t pgstart;
	size_t pgend;
	unsigned int purged;
};
